# frozen_string_literal: true

module Fxlang
  class Parser
    attr_reader :pattern, :key_map

    KEY_NAME = 'keyName'
    DELIMITER = 'XXX'
    TEMPLATE_PATTERN = /{{ *(?<#{KEY_NAME}>[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*) *}}/.freeze

    def initialize(template)
      @key_map = {}
      @pattern = template.gsub(TEMPLATE_PATTERN) do |match|
        key = match.sub(/\A{{ */, '').sub(/ *}}\z/, '')
        @key_map[key] = group_name = key.gsub(/\./, DELIMITER)

        "(?<#{group_name}>.*)"
      end
    end

    def parse(target)
      matcher = target.match(pattern)

      key_map.each_with_object({}) do |(full_key, group), result|
        temp_keys = full_key.split('.')
        leaf_key = temp_keys.pop

        # rubocop:disable Lint/UnmodifiedReduceAccumulator
        temp_keys.reduce(result) { |rtn, key| rtn[key] = {} }.merge!(leaf_key => matcher[group])
        # rubocop:enable Lint/UnmodifiedReduceAccumulator
      end
    end
  end
end
